/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.belfalas.simy86;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author belfalas
 */
public class Memoria {
    
    private static ByteBuffer memoria;
    
    public Memoria (int tamanho){
        memoria = ByteBuffer.allocate(tamanho);
        memoria.order(ByteOrder.LITTLE_ENDIAN);
    }
    
    public short readUnsignedByte(){
        return ByteBufferWorker.getUnsignedByte(memoria);
    }
    
    public short readUnsignedByte(int position){
        return ByteBufferWorker.getUnsignedByte(memoria, position);
    }
    
    public long readUnsignedWord(){
        return ByteBufferWorker.getUnsignedInt(memoria);
    }
    
    public long readUnsignedWord(int position){
        return ByteBufferWorker.getUnsignedInt(memoria, position);
    }
    
    public int readSignedWord(){
        return memoria.getInt();
    }
    
    public int readSignedWord(int position){
        if (position >= memoria.capacity()) {
            System.out.println(position);
        }
        return memoria.getInt(position);
    }
    
    public void writeUnsignedWord(long word){
        ByteBufferWorker.putUnsignedInt(memoria, word);
    }
    
    public void writeUnsignedWord(long word, int position){
        ByteBufferWorker.putUnsignedInt(memoria, position, word);
    }
    
    public void writeSignedWord (int word){
        memoria.putInt(word);
    }
    
    public void writeSignedWord (int word, int position){
        memoria.putInt(position, word);
        if (position >= 0x00100000) try {
            Thread.sleep(20);
        } catch (InterruptedException ex) {
            Logger.getLogger(Memoria.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void writeUnsignedByte(short word){
        ByteBufferWorker.putUnsignedByte(memoria, word);
    }
    
    public void writeUnsignedByte(short word, int position){
        ByteBufferWorker.putUnsignedByte(memoria, position, word);
        if (position >= 0x00100000) try {
            Thread.sleep(5);
        } catch (InterruptedException ex) {
            Logger.getLogger(Memoria.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void dumpMemory(int position){
        for (int i=0; i<10; i++){
            System.out.printf("%04x: %x\n",position+i, this.readUnsignedByte(position+i));
        }
    }
    
    public int getFinal(){
        return memoria.limit();
    }
    
    public ByteBuffer getVideoMemory(){
        int size = 320*240*4;
        int position = 0x001f8000 - size;
        byte[] buffer = memoria.array();
        byte[] dst = new byte[size];
        System.arraycopy(buffer, position, dst, 0, size);
        ByteBuffer bb = ByteBuffer.wrap(dst);
        bb.order(memoria.order());
        return bb;
    }
    
}
